//client.vala
//valac --pkg jsonrpc-glib-1.0 jsonclient.vala
using Jsonrpc;

public class RpcClient:GLib.Object{
	[CCode(notify = false)]
	bool rpcx {set;get;default=false;}
	public Jsonrpc.Client c;
	public GLib.MainLoop loop1;
	public int counter {set;get;default=0;}

	public owned void rpcConnect(string host,uint16 port){
		Resolver resolver = Resolver.get_default ();
		List<InetAddress> addresses = resolver.lookup_by_name (host, null);
		InetAddress address = addresses.nth_data (0);
		SocketClient client = new SocketClient ();
		SocketConnection conn = client.connect(new InetSocketAddress (address, port));
		c = new Jsonrpc.Client(conn);
		this.notify.connect((s,p)=>{
			print("%s changed\n",p.get_name());
			GLib.AsyncReadyCallback f = (o,r)=>{
				GLib.Variant res;
				c.call_async.end(r,out res);
				stdout.printf("%d : %s\n",this.counter,res.get_string());
				counter = counter+1;
				if (counter>5){
					this.loop1.quit();
				}
			};
			this.get_text("counter add one",f);
		});
	}

	public void rpcClient(){
		string[] v = {"Hello friend.","无限恐怖","abcde"};
		var params = new Variant.strv(v);
		var loop = new GLib.MainLoop();
		int n=0;
		Variant res;
		
		GLib.AsyncReadyCallback f = (o,r)=>{
				Variant res1;
				c.call_async.end(r,out res1);
				n++;
				stdout.printf("async : %s\n",res1.get_string());
				lock(rpcx){
					rpcx = false;
				}
				if(n>5)
					loop.quit();
			};
		var thread = new GLib.Thread<int>("subproc",()=>{
				while(true){
					bool running = false;
					lock(rpcx){
						running = rpcx;
					}
					if(running==false){
						print("add call async\n");
						try{
							c.call_async.begin("Arith.Hello",params,null,f);
							lock(rpcx){
								rpcx = true;
							}
						}catch (Error e) {
							stdout.printf ("Error: %s\n", e.message);
							loop.quit();
						}
					}
				}
			});
		
//串行执行
//		try{
//			for (int i=0;i<3;i++){
//				var ok = c.call("Arith.Hello",params,null,out res);
//				if(ok){
//					stdout.printf("sync: %s\n",res.get_string());
//				}else{
//					stdout.printf("error\n");
//				}
//			}
//		}catch (Error e) {
//			stdout.printf ("sync Error: %s\n", e.message);
//		}
		
		loop.run();
	}
	public void get_text(string s,GLib.AsyncReadyCallback f){
		string[] v = {"Return:",s};
		var params = new Variant.strv(v);
		c.call_async.begin("Arith.Hello",params,null,f);
	}
	public void init(){
		this.loop1 = new GLib.MainLoop();
	}
	public void run_loop(){
		this.loop1.run();
	}
	public void close(){
		c.close();
	}
}
void main(){
	var c = new RpcClient();
	c.rpcConnect("localhost",6666);
	//c.rpcClient();
	c.init();
	c.counter++;
	c.run_loop();
	c.close();
	stdout.printf("end\n");
}
